/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.wsinfra.wsr.storage.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.Calendar;

import org.apache.xmlbeans.GDuration;

import cgl.narada.wsinfra.schemas.addressing.EndpointReferenceType;
import cgl.narada.wsinfra.util.MarshallingUtils;
import cgl.narada.wsinfra.wsr.storage.WsrGroupInfo;


/** This interface encapsulates information pertaining to a group. 
 * @author sima patel
 * $Date: 2005/03/18 20:18:23 $
 * $Revision: 1.3 $
*/

public class WsrGroupInfoImpl implements WsrGroupInfo {
  
    private String groupId;
    private boolean hasGroupExpiryTime= false;
    private Calendar groupExpiryTime;
    private boolean hasGroupMaxIdleDuration=false;
    private GDuration groupMaxIdleDuration;
    private boolean hasLastSequenceNumber=false;
    private long lastSequenceNumber;
    private long sequenceNumberLastDelivered;
    private boolean isSource = true;
    private EndpointReferenceType source;
    private EndpointReferenceType destination;
    private MarshallingUtils marshaller = MarshallingUtils.getInstance();
    private String moduleName = "WsrGroupInfoImpl: ";

    public WsrGroupInfoImpl(){}

    public WsrGroupInfoImpl(String groupId){
        setGroupId(groupId);
    }
    public WsrGroupInfoImpl(String groupId, boolean isSource,
                            EndpointReferenceType source, 
                            EndpointReferenceType destination){
        this(groupId);
        setIsSource(isSource);
        setSource(source);
        setDestination(destination);
    }
    public WsrGroupInfoImpl(String groupId, boolean isSource,
                            byte[] marshalledBytesOfAddresses){
        this(groupId);
        setIsSource(isSource);
        ByteArrayInputStream baInputStream = 
        new ByteArrayInputStream(marshalledBytesOfAddresses);
        DataInputStream din = new DataInputStream(baInputStream);
        try{
            source = marshaller.readEprFromStream(din);
            destination = marshaller.readEprFromStream(din);
        } catch (Exception ioe) {
            System.out.println(moduleName + "Error while un-marshalling" + ioe);
            ioe.printStackTrace();
        }/** end try-catch block*/

    }
    /** Retrieve the groupId. */
    public String getGroupId() {
        return groupId;
    }
    /** sets the groupId. */
    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }
    /** Checks if GroupExpiryTime parameter is present */
    public boolean hasGroupExpiryTime(){
        return hasGroupExpiryTime;
    }
    /** sets the hasGroupExpiryTime parameter */
    public void setHasGroupExpiryTime(boolean hasGroupExpiryTime){
        this.hasGroupExpiryTime = hasGroupExpiryTime;
    }
    /** Returns the GroupExpiryTime */
    public Calendar getGroupExpiryTime(){
        return groupExpiryTime;
    }
    /** sets the groupExpiryTime */
    public void setGroupExpiryTime(Calendar groupExpiryTime){
        this.groupExpiryTime = groupExpiryTime;
        if(groupExpiryTime != null){
           setHasGroupExpiryTime(true);
        }else{
           setHasGroupExpiryTime(false);
        }
    }
    /** Checks if GroupMaxIdleDuration parameter is present */
    public boolean hasGroupMaxIdleDuration(){
        return hasGroupMaxIdleDuration;
    }
    /** sets the hasGroupExpiryTime parameter */
    public void setHasGroupMaxIdleDuration(boolean hasGroupMaxIdleDuration){
        this.hasGroupMaxIdleDuration = hasGroupMaxIdleDuration;
    }
    /** Returns the groupMaxIdleDuration */
    public GDuration getGroupMaxIdleDuration(){
        return groupMaxIdleDuration;
    }
    /** sets the groupMaxIdleDuration */
    public void setGroupMaxIdleDuration(GDuration groupMaxIdleDuration){
        this.groupMaxIdleDuration = groupMaxIdleDuration;
        if(groupMaxIdleDuration != null){
         setHasGroupMaxIdleDuration(true);
        }else{
           setHasGroupMaxIdleDuration(false);
        }
    }
    /** Check to see if we have information regarding the last message of a 
    group. */
    public boolean hasLastSequenceNumber() {
        return hasLastSequenceNumber;
    }

    /** Sets the variable with boolean value if we have information regarding 
    the last message of the group */
    public void setHasLastSequenceNumber(boolean hasLastSequenceNumber){
        this.hasLastSequenceNumber = hasLastSequenceNumber;
    }
    /** If we do have information regarding the last message of a group,
    proceed to retrieve it */
    public long getLastSequenceNumber() {
        return lastSequenceNumber;
    }
    /** sets the hasLastSequenceNumber parameter */
    public void setLastSequenceNumber(long lastSequenceNumber) {
        this.lastSequenceNumber = lastSequenceNumber;
        setHasLastSequenceNumber(true);
    }
    /** If we do have information regarding the Sequence Number last
    Delivered of a group, proceed to retrieve it */
    public long getSequenceNumberLastDelivered() {
        return sequenceNumberLastDelivered;
    }
    /** sets the sequenceNumberLastDelivered parameter */
    public void setSequenceNumberLastDelivered(long sequenceNumberLastDelivered) {
        this.sequenceNumberLastDelivered = sequenceNumberLastDelivered;
        
    }
    /** Checks if this node is the source of the group in question*/
    public boolean isSource() {
        return isSource;
    }
    /** sets the isSource parameter */
    public void setIsSource(boolean isSource){
        this.isSource = isSource;
    }
    /** Checks if this node is the destination of the group in question */
    public boolean isDestination() {
        if (isSource) {
            return false;
        }
        return true;
    }
    /** Returns the source of this group */
    public EndpointReferenceType getSource() {
        return source;
    }
    /** sets the source of this group */
    public void setSource(EndpointReferenceType source){
        this.source = source;
    }

    /** Returns the destination of this group */
    public EndpointReferenceType getDestination() {
        return destination;
    }
    /** sets the destination of this group */
    public void setDestination(EndpointReferenceType destination){
        this.destination = destination;
    }
    /** Get a byte representation of the Source and Destination Addresses */
    public byte[] getBytesOfAddresses() {
        ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baOutputStream);
        byte[] marshalledBytes= null;
        try {
            marshaller.writeEprToStream(source, dout);
            marshaller.writeEprToStream(destination, dout);
            marshalledBytes = baOutputStream.toByteArray();
        } catch (Exception ioe) {
            System.out.println(moduleName + "Error while marshalling" + ioe);
        } /** end try-catch block*/
        return marshalledBytes;
    }
    public String toString() {
        String stringRep = "WsrGroupInfo ";
        stringRep += ("GroupId=" + groupId + ")");
        stringRep += (", Source=" + source + ", Destination=" +  destination);
        if(hasGroupExpiryTime){
            stringRep += ( " GroupExpiryTime=" + groupExpiryTime);
        }
        if(hasGroupMaxIdleDuration){
            stringRep += ( " GroupMaxIdleDuration=" + groupMaxIdleDuration);
        }
        if (hasLastSequenceNumber) {
            stringRep += ( " Last Sequence Number=" + lastSequenceNumber);
        }
        return stringRep;
    }
}